`include "sdr_head.v"

module sdr_init(
    input                   clk,
    input                   soft_rst,
    input                   init_en,
    output reg              init_done,
    output      [19 : 0]    init_bus
);

    localparam  st0  = 3'd0;
    localparam  st1  = 3'd1;
    localparam  stn1 = 3'd2;
    localparam  sto1 = 3'd3;
    localparam  tp1  = 3'd4;
    localparam  tp3  = 3'd5;
    localparam  send = 3'd6;

    reg     [3  : 0]    cmd;
    reg     [14 : 0]    cnt;
    reg     [2  : 0]    state;
    reg     [12 : 0]    sdr_a;
    reg     [1  : 0]    sdr_ba;
    reg                 sdr_cke;
    wire                sdr_cs_n, sdr_ras_n;
    wire                sdr_cas_n, sdr_we_n;

    assign {sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n} = cmd;
    assign init_bus = {sdr_cke, sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n, sdr_a, sdr_ba};

    //==========状态机==========//
    always @(posedge clk)
    begin
        if (!soft_rst) begin
                cmd <= `INH;
                sdr_cke <= 1'b0;
                init_done <= 1'b0;
                sdr_a <= 13'b0;
                sdr_ba <= 2'b0;
                cnt <= 15'b0;
                state <= st0;
        end
        else begin
            case (state)
                st0 : begin
                    if (cnt < `T100us)
                        cnt <= cnt + 1'b1;
                    else begin
                        cnt <= 15'b0;
                        sdr_cke <= 1'b1;
                        cmd <= `NOP;
                        state <= st1;
                    end
                end
                st1 : begin
                    sdr_a[10] <= 1'b1;
                    cmd <= `PRE;
                    state <= stn1;
                end
                stn1 : begin
                    if (cnt < `TRP) begin
                        cnt <= cnt + 1'b1;
                        cmd <= `NOP;
                    end
                    else begin
                        cnt <= 15'b0;
                        cmd <= `REF;
                        state <= sto1;
                    end
                end
                sto1 : begin
                    if (cnt < `TRFC) begin
                        cnt <= cnt + 1'b1;
                        cmd <= `NOP;
                    end
                    else begin
                        cnt <= 15'b0;
                        cmd <= `REF;
                        state <= tp1;
                    end
                end
                tp1 : begin
                    if (cnt < `TRFC) begin
                        cnt <= cnt + 1'b1;
                        cmd <= `NOP;
                        end
                    else begin
                        cnt <= 15'b0;
                        cmd <= `LMR;
                        sdr_a <= `CODE;
                        sdr_ba <= 2'b0;
                        state <= tp3;
                    end
                end
                tp3 : begin
                    if (cnt < `TMRD) begin
                        cnt <= cnt + 1'b1;
                        cmd <= `NOP;
                    end
                    else begin
                        cnt <= 15'b0;
                        init_done <= 1'b1;
                        state <= send;
                    end
                end
                send : begin
                    state <= send;
                end
                default : state <= send;
            endcase
        end
    end

    //==========序列机==========//
    // localparam l0  = 10000;
    // localparam l1  = l0  + 1;
    // localparam ln1 = l1  + `TRP;
    // localparam lo1 = ln1 + `TRFC;
    // localparam lp1 = lo1 + `TRFC;
    // localparam lp3 = lp1 + `TMRD;

    // always @(posedge clk)
    // begin : LSM_1
    //     if (!soft_rst)
    //         cnt <= 15'b0;
    //     else
    //         if ((cnt < lp3) && init_en)
    //             cnt <= cnt + 1'b1;
    //         else
    //             cnt <= cnt;
    // end

    // always @(posedge clk)
    // begin : LSM_2
    //     if (!soft_rst) begin
    //             cmd <= `INH;
    //             sdr_cke <= 1'b0;
    //             init_done <= 1'b0;
    //             sdr_a <= 13'b0;
    //             sdr_ba <= 2'b0;
    //     end
    //     else begin
    //         case (cnt)
    //             l0 : begin
    //                 sdr_cke <= 1'b0;
    //                 cmd <= `NOP;
    //             end
    //             l1 : begin
    //                 sdr_a[10] <= 1'b1;
    //                 cmd <= `PRE;
    //             end
    //             lm1 : cmd <= `REF;
    //             lo1 : cmd <= `REF;
    //             lp1 : begin
    //                 cmd <= `LMR;
    //                 sdr_a <= `CODE;
    //                 sdr_ba <= 2'b0;
    //             end
    //             lp3 : init_done <= 1'b1;
    //             default : cmd <= `NOP;
    //         endcase
    //     end
    // end

endmodule 